package pl.game;

import java.util.ArrayList;
import java.util.List;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.primitive.Line;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;
import org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.anddev.andengine.input.touch.detector.SurfaceScrollDetector;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;


public class Main extends BaseGameActivity implements IScrollDetectorListener,
		IOnSceneTouchListener {
	// ===========================================================
	// Constants
	// ===========================================================

	/*
	 * Initializing the Random generator produces a comparable result over
	 * different versions.
	 */

	private static final int CAMERA_WIDTH = 320;
	private static final int CAMERA_HEIGHT = 240;

	// ===========================================================
	// Fields
	// ===========================================================

	private ZoomCamera mCamera;
	private BitmapTextureAtlas backgroundTexture;
	private TextureRegion baclgroundFaceTextureRegion;
	private Sprite background;

	ScrollDetector mScrollDetector;

	private List<MyTile> tiles; 
	private List<MySprite> sprites; 
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public Engine onLoadEngine() {
		this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		this.mCamera.setBounds(-512, 512, -512, 512);
		this.mCamera.setBoundsEnabled(true);
		return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,	new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),	this.mCamera));
	}

	@Override
	public void onLoadResources() {
		this.generateCountriesTextures();
	}

	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());
		final Scene scene = new Scene(1);
		scene.setBackground(new ColorBackground(0.0f, 0.0f, 0.0f));

		this.mScrollDetector = new SurfaceScrollDetector(this);
		this.mScrollDetector.setEnabled(true);
		scene.setOnSceneTouchListener(this);

		this.drawTextures(scene);

		return scene;
	}

	@Override
	public void onLoadComplete() {
		System.out.println("onLoadComplete");
	}

	@Override
	public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
			float pDistanceX, float pDistanceY) {
		this.mCamera.offsetCenter(-pDistanceX, -pDistanceY);
	}

	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
		return true;
	}

	// ===========================================================
	// Methods
	// ===========================================================

	public void generateCountriesTextures(){
		this.backgroundTexture = new BitmapTextureAtlas(512, 512, TextureOptions.BILINEAR);
		this.baclgroundFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(backgroundTexture, this, "gfx/map.png", 0, 0);
		this.mEngine.getTextureManager().loadTexture(this.backgroundTexture);
		
		tiles = new ArrayList<MyTile>();
		sprites = new ArrayList<Main.MySprite>();
		
		BitmapTextureAtlas texture1 = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR);
		TextureRegion textureRegion1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(texture1, this, "gfx/flag_1.png", 0, 0);
		this.mEngine.getTextureManager().loadTexture(texture1);
		MyTile tile1 = new MyTile(texture1, textureRegion1);
		tiles.add(tile1);

		BitmapTextureAtlas texture2 = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR);
		TextureRegion textureRegion2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(texture2, this, "gfx/flag_2.png", 0, 0);
		this.mEngine.getTextureManager().loadTexture(texture2);
		MyTile tile2 = new MyTile(texture2, textureRegion2);
		tiles.add(tile2);
		
		BitmapTextureAtlas texture3 = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR);
		TextureRegion textureRegion3 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(texture3, this, "gfx/flag_1.png", 0, 0);
		this.mEngine.getTextureManager().loadTexture(texture3);
		MyTile tile3 = new MyTile(texture3, textureRegion3);
		tiles.add(tile3);

		BitmapTextureAtlas texture4 = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR);
		TextureRegion textureRegion4 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(texture4, this, "gfx/flag_2.png", 0, 0);
		this.mEngine.getTextureManager().loadTexture(texture4);
		MyTile tile4 = new MyTile(texture4, textureRegion4);
		tiles.add(tile4);
	}
	
	public void drawTextures(Scene scene){
		final int centerX = (CAMERA_WIDTH - this.baclgroundFaceTextureRegion.getWidth()) / 2;
		final int centerY = (CAMERA_HEIGHT - this.baclgroundFaceTextureRegion.getHeight()) / 2;

		background = new Sprite(centerX, centerY, this.baclgroundFaceTextureRegion);
		scene.getLastChild().attachChild(background);

		MySprite newSprite1 = new MySprite(50, 200, tiles.get(0).mFaceTextureRegion);
		scene.getLastChild().attachChild(newSprite1);
		scene.registerTouchArea(newSprite1);
		scene.setTouchAreaBindingEnabled(true);

		MySprite newSprite2 = new MySprite(100, 100, tiles.get(1).mFaceTextureRegion);
		scene.getLastChild().attachChild(newSprite2);
		scene.registerTouchArea(newSprite2);
		scene.setTouchAreaBindingEnabled(true);
		
		MySprite newSprite3 = new MySprite(200, 250, tiles.get(2).mFaceTextureRegion);
		scene.getLastChild().attachChild(newSprite3);
		scene.registerTouchArea(newSprite3);
		scene.setTouchAreaBindingEnabled(true);

		MySprite newSprite4 = new MySprite(100, 300, tiles.get(3).mFaceTextureRegion);
		scene.getLastChild().attachChild(newSprite4);
		scene.registerTouchArea(newSprite4);
		scene.setTouchAreaBindingEnabled(true);
		
		newSprite1.addNeighbour(newSprite4);
		newSprite1.addNeighbour(newSprite2);
		newSprite1.addNeighbour(newSprite3);
		newSprite1.addPaths();
		
		newSprite3.addNeighbour(newSprite4);
		newSprite3.addNeighbour(newSprite2);
		newSprite3.addNeighbour(newSprite1);
		newSprite3.addPaths();	
	}
	
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================

	class MyTile {
		private Texture mTexture;
		private TextureRegion mFaceTextureRegion;

		public MyTile(Texture mTexture, TextureRegion mFaceTextureRegion) {
			this.mTexture = mTexture;
			this.mFaceTextureRegion = mFaceTextureRegion;
		}

		public Texture getmTexture() {
			return mTexture;
		}

		public void setmTexture(Texture mTexture) {
			this.mTexture = mTexture;
		}

		public TextureRegion getmFaceTextureRegion() {
			return mFaceTextureRegion;
		}

		public void setmFaceTextureRegion(TextureRegion mFaceTextureRegion) {
			this.mFaceTextureRegion = mFaceTextureRegion;
		}
	}

	class MySprite extends Sprite {

		private IEntity mySprite;
		private List<IEntity> neighbours;
		private List<IEntity> paths;
		private boolean active;
		private boolean captured;
		
		public MySprite(float pX, float pY, TextureRegion pTextureRegion) {
			super(pX, pY, pTextureRegion);
			mySprite = this;
			neighbours = new ArrayList<IEntity>();
			paths = new ArrayList<IEntity>();
			active = false;
			captured = false;
		}

		public boolean isCaptured() {
			return captured;
		}

		public void setCaptured(boolean captured) {
			this.captured = captured;
		}

		public void addNeighbour(IEntity neighbour) {
			neighbours.add(neighbour);
		}

		@Override
		public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
				float pTouchAreaLocalX, float pTouchAreaLocalY) {

			if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) {
				mEngine.runOnUpdateThread(new Runnable() {
					@Override
					public void run() {
						for (IEntity element : paths) {
							if (active) {
								mEngine.getScene().getLastChild().detachChild(element);
								active = false;
							} else {
								mEngine.getScene().getLastChild().attachChild(element);
								active = true;
							}
						}
					}
				});
			}
			return true;
		}

		public void addPaths() {
			for (IEntity neighbour : neighbours) {
				Line line = new Line(neighbour.getX(), neighbour.getY()	+ this.getHeight(), this.getX(), this.getY() + this.getHeight(), 4);
				line.setColor(0.0f, 0.0f, 0.0f);
				paths.add(line);
			}
		}
	}
}